home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
- #
- # shell script to generate a sendmail chn-tbl.m4 file containing all
- # the routing information for this host from a set of channel tables.
- #
- if [ $# -le 1 ]
- then echo "usage: $0 [-o outfile] -chn file..."
- exit
- fi
-
- #
- # first, create the awk programs that compile the channel tables
- #
-
- rm -f $$.*
- outf=chn-tbl.m4
-
- #
- # Standard format channel compiler
- #
- cat > $$.std.awk <<'EOF'
- NR==1 {
- MINCLSIZE = 3
- c = 1
- mailer = substr(mailer, 2)
- cl_outl = prefix "classl"
- cl_outf = prefix "classf"
- printf "\n# %s (%s channel)\n", file, mailer
- }
-
- NF==1 { $2 = substr($1, 1, index($1,".")-1) } # shorthand
-
- /%s/ {
- # process wildcards
- lhs = sprintf($1,"$+","$+","$+")
- rhs = sprintf($1,"$2","$3","$4")
- dest = sprintf($2,"$2","$3","$4")
- printf "R$+@%s\t\t$@<$1@%s>%s.%s\n", lhs, rhs, dest, mailer >> S16
- break
- }
-
- {
- i = index($1, ".")
- subdom = substr($1,1,i-1)
- restdom = substr($1,i+1)
-
- if (subdom == $2 && restdom != "")
- link["$2/" restdom] = link["$2/" restdom] " " subdom
- else
- link[ $2 "/" restdom ] = link[ $2 "/" restdom ] " " subdom
- }
-
- END {
- for (i in link)
- { j = index(i,"/")
- dest = substr(i, 1, j-1)
- rdom = substr(i, j+1)
- n = split(link[i], sub, " ")
- if (n >= MINCLSIZE && c <= length(classes))
- { C = substr(classes, c, 1)
- c++
- printf "C%s%s\n", C , link[i] >> cl_outf
- printf "R$+@$=%s.%s\t\t$@<$1@$2.%s>%s.%s\n", \
- C, rdom, rdom, dest, mailer
- }
- else
- { host = dest
- for (j=1; j<=n; j++)
- { if (dest == "$2") host = sub[j]
- printf "R$+@%s.%s\t\t$@<$1@%s.%s>%s.%s\n", \
- sub[j], rdom, sub[j], rdom, host, mailer
- }
- }
- }
-
- print "" >>cl_outf
- print substr(classes, c) > cl_outl
- }
- EOF
-
- #
- # Janet channel compiler
- #
- cat > $$.janet.awk <<'EOF'
- NR==1 {
- printf "\n# %s (Janet channel)\n", file
- swap1 = sprintf("R$+@$+\t\t$:$>9$1@$2\t\tconvert to NRS style")
- swap2 = sprintf("R$+@$+\t\t$:$>9$1@$2\t\tconvert back to 822 style")
- }
-
- NF==1 { $2 = $1 } # shorthand
-
- /%s/ {
- if (wcnt++ == 0) print swap1 >> S16
-
- # process wildcards
- lhs = sprintf($1,"$+","$+","$+")
- rhs = sprintf($1,"$2","$3","$4")
- dest = sprintf($2,"$2","$3","$4")
- if (rhs == dest)
- jntaddr = "$1@" dest
- else
- jntaddr = "$1%" rhs "@" dest
- printf "R$+@%s\t\t$@<%s>%s.janet\n", lhs, jntaddr, dest >> S16
- break
- }
-
- {
- if (cnt++ == 0) print swap1
-
- if ($1 == $2)
- jntaddr = "$1@" $2
- else
- jntaddr = "$1%" $1 "@" $2
- printf "R$+@%s\t\t$@<%s>%s.janet\n", $1, jntaddr, $2
- }
-
- END {
- if (cnt > 0) print swap2
- if (wcnt > 0) print swap2 >> S16
- }
- EOF
-
- #
- # UUCP channel compiler
- #
- cat > $$.uucp.awk <<'EOF'
- NR==1 {
- MINCLSIZE = 3
- c = 1
- link[""]=""
- cl_outl = prefix "classl"
- cl_outf = prefix "classf"
- printf "\n# %s (UUCP channel)\n", file
- printf "R$+@$+\t\t\t$:$>8$1@$2\t\tconvert to uucp addresses\n"
- }
-
- {
- i = index($1, ".")
- subdom = substr($1,1,i-1)
- restdom = substr($1,i+1)
- udest = subdom "!%s"
-
- if (NF == 1) $2 = udest # shorthand
-
- if (udest == $2)
- link[ "/" restdom ] = link[ "/" restdom ] " " subdom
- else
- { pathl = length($2) - length(udest)
- if ( substr($2, pathl) == ("!" udest) )
- { path = substr($2, 1, pathl-1)
- link[ path "/" restdom ] = link[ path "/" restdom ] " " subdom
- }
- else
- { i = index($2, "!")
- host = substr($2,1,i-1)
- addr = sprintf( substr($2,i+1), "$1")
- printf "R%s!$+\t\t$@<%s>%s.uucp\n", $1, addr, host
- }
- }
- }
-
- END {
- for (i in link)
- { j = index(i, "/")
- path = substr(i, 1, j-1)
- rdom = substr(i, j+1)
- p = index(path, "!")
- n = split(link[i], sub, " ")
- if (n >= MINCLSIZE && c <= length(classes))
- { C = substr(classes, c, 1)
- c++
- printf "C%s%s\n", C, link[i] >>cl_outf
- if (path == "")
- { host = "$1"
- addr = ""
- }
- else if (p == 0)
- { host = path
- addr = "$1!"
- }
- else
- { host = substr(path,1,p-1)
- addr = substr(path,p+1) "!$1!"
- }
- printf "R$=%s.%s!$+\t\t$@<%s$2>%s.uucp\n", C, rdom, addr, host
- }
- else
- { for (j=1; j<=n; j++)
- { if (path == "")
- { host = sub[j]
- addr = ""
- }
- else if (p == 0)
- { host = path
- addr = sub[j] "!"
- }
- else
- { host = substr(path,1,p-1)
- addr = substr(path,p+1) "!" sub[j] "!"
- }
- printf "R%s.%s!$+\t\t$@<%s$1>%s.uucp\n", \
- sub[j], rdom, addr, host
- }
- }
- }
- print "" >>cl_outf
- print substr(classes, c) > cl_outl
- print "\nR$+!$+\t\t\t$:$>7$1!$2\t\tconvert back to 822 style\n"
- }
- EOF
-
- #
- # News channel compiler
- #
- cat > $$.news.awk << 'EOF'
- NR==1 { printf "\n# %s (news channel)\n", file }
- {
- lhs = sprintf($1,"$+","$+","$+")
- rhs = sprintf($1,"$1","$2","$3")
- dest = sprintf($2,"$1","$2","$3")
-
- if (NF == 1)
- printf "R%s\t\t$@<%s>news\n", lhs, rhs
- else
- printf "R%s\t\t$@$>3 %s@%s\n", lhs, rhs, dest
- }
- EOF
-
-
- #
- # Top level domain relay compiler
- #
- cat > $$.top.awk <<'EOF'
- NR==1 {
- MINCLSIZE = 3
- c = 1
- cl_outl = prefix "classl"
- cl_outf = prefix "classf"
- relay[""] = ""
- }
- $1=="DEFAULT" || $1=="$=T" { default = $2 ; break }
- $1=="ALL" || $1=="$+" { all = $2 ; break }
-
- { relay[$2] = relay[$2] " " $1 }
-
- END {
- for (i in relay)
- { n = split(relay[i], doms, " ")
- if (n >= MINCLSIZE && c <= length(classes))
- { C = substr(classes, c, 1)
- c++
- printf "C%s%s\n", C, relay[i] >> cl_outf
- printf "R$+@$+.$=%s\t\t$@$>16$1%%$2.$3@%s\n", C, i
- }
- else
- { for (j=1; j<=n; j++)
- printf "R$+@$+.%s\t\t$@$>16$1%%$2.%s@%s\n", \
- doms[j], doms[j], i
- }
- }
- if (default) printf "R$+@$+.$=T\t\t$@$>16$1%%$2.$3@%s\n", default
- if (all) printf "R$+@$+\t\t$@$>16$1%%$2@%s\n", all
-
- print "" >>cl_outf
- print substr(classes, c) > cl_outl
- }
- EOF
-
- #---------------------------------------
-
- #
- # awk scripts for compiling to ida databases
- #
- cat > $$.std.ida.awk <<'EOF'
- NR==1 {
- mailer = substr(mailer, 2)
- printf "\n# %s (%s channel)\n", file, mailer
- printf "R$+@$+\t\t$:$(%s $2 $@ $1 $: $1@$2 $)\t\tlookup database\n",key
- printf "R<$+>$+.%s\t\t$@<$1>$2.%s\t\tfound a match\n", mailer,mailer
- }
- NF==1 { $2 = substr($1, 1, index($1,".")-1) } # shorthand
- { printf "%s\t<%%s@%s>%s.%s\n", $1, $1, $2, mailer > dbmf }
- EOF
-
- cat > $$.janet.ida.awk <<'EOF'
- NR==1 {
- printf "\n# %s (Janet channel)\n", file
- printf "R$+@$+\t\t$:$>9$1@$2\t\tconvert to NRS style\n"
- printf "R$+@$+\t\t$:$(%s $2 $@ $1 $: $1@$2 $)\t\tlookup database\n",key
- printf "R<$+>$+.janet\t\t$@<$1>$2.janet\t\tfound a match\n"
- }
- NF==1 { $2 = $1 } # shorthand
- {
- if ($1 == $2)
- jntaddr = "%s@" $2
- else
- jntaddr = "%s%%" $1 "@" $2
-
- printf "%s\t<%s>%s.janet\n", $1, jntaddr, $2 > dbmf
- }
- END { printf "\nR$+@$+\t\t$:$>9$1@$2\t\tconvert back to 822 style\n" }
- EOF
-
-
- #---------------------------------------
-
- #
- # compile the tables; output goes into various files
- #
-
- strip="sed -e /#/s/#.*// -e /^\$/d"
- classes="NOPQRSUVWXYZ"
- dbkeys="BCDEFHIJ"
- cp /dev/null $$.classf
-
- while [ $# -gt 0 ]
- do
- case $1 in
-
- -o) outf=$2
- ;;
-
- -local) $strip -e 's/^LHOST\./$=w./' $2 | awk '
- { printf "R$+@%s\t\t$@$1@$J\n", $1 >> S15
- printf "R$+@%s\t\t$@<$1@$J>error\n", $1 >> S17
- }' S15=$$.S15 S17=$$.S17 -
- ;;
-
- -ether|-tcp|-csnet|-decnet|-xerox)
- $strip $2 | awk -f $$.std.awk mailer=$1 file=$2 prefix=$$. \
- classes=$classes S16=$$.S16 - >> $$.S17
- classes=`cat $$.classl`
- ;;
-
- -janet) $strip $2 | awk -f $$.janet.awk file=$2 S16=$$.S16 - >> $$.S17
- ;;
-
- -uucp) $strip $2 | awk -f $$.uucp.awk file=$2 prefix=$$. \
- classes=$classes - >> $$.S17
- classes=`cat $$.classl`
- ;;
-
- -news) $strip $2 | awk -f $$.news.awk file=$2 - >> $$.S18
- ;;
-
- -top) $strip $2 | awk -f $$.top.awk prefix=$$. \
- classes=$classes - >> $$.S16
- classes=`cat $$.classl`
- ;;
-
- -ida) shift
- key=`expr substr $dbkeys 1 1`
- dbkeys=`expr substr $dbkeys 2 26`
- dbmfile=`basename $2 .chn`
-
- case $1 in
- -janet) $strip $2 | awk -f $$.janet.ida.awk file=$2 \
- key=$key dbmf=$dbmfile.ida - >> $$.S17
- ;;
-
- *) $strip $2 | awk -f $$.std.ida.awk mailer=$1 file=$2 \
- key=$key dbmf=$dbmfile.ida - >> $$.S17
- ;;
- esac
-
- dbm load $dbmfile.ida $dbmfile
- echo "OK$key`pwd`/$dbmfile" >> $$.S17
- rm $dbmfile.ida
- ;;
-
- *) echo "usage: $0 [-o file] -chn file..."
- rm -f $$.*
- exit 1
- ;;
- esac
- shift
- shift
- done
-
- #---------------------------------------
-
- #
- # now glue all the bits together
- #
-
- #
- # The header
- #
- cat > $outf <<EOF
- ###############################################################################
- #####
- ##### @(#)$outf UK-2.1 sendmail configuration 18/11/88
- #####
- ##### The mailer selection and routing
- #####
- ###############################################################################
-
- # classes
- EOF
-
- #
- # the classes
- #
- while read class group
- do
- echo "$group" | fmt | sed "s/^/$class/"
- done < $$.classf >> $outf
-
- #
- # the rules
- #
- cat - $$.S15 >> $outf <<'EOF'
-
- ###########################################
- # Ruleset 15 -- local domain handling #
- ###########################################
-
- #
- # This rule converts various forms of local domain names
- # into the standard ($J) name
- #
-
- S15
- ifdef(`MULTIHOST',
- `R$+@$=w.$J $@$1@$J host specific name')
- EOF
-
- cat - $$.S16 >> $outf <<'EOF'
-
- #############################
- # Ruleset 16 -- routing #
- #############################
-
- #
- # This rule trys to find an "<address>host.network" triple for a given
- # domain address. Given a domain address "u@a.b.c.d", it calls the
- # channel matcher with u@a.b.c.d, and if nothing matched, it calls
- # the channel matcher again, with "u%a.b.c.d@b.c.d" and "u%a.b.c.d@c.d".
- # If there's still no match, then the top level domain relaying is done
- # e.g. "u%a.b.c.d@d" -> "u%a.b.c.d@x.y.z" and the rule is retried.
- #
-
- S16
- R$+@$+ $:$>17$1@$2 initial routing
- R<$+>$+ $@<$1>$2 success, return triple
-
- # initial match failed, retry with successively higher level domains
- R<$+@$+> $:<$1%$2@$2> u@a.b.c -> u%a.b.c@a.b.c
- R<$+@$-.$+> $>17$1@$3 retry routing
- R<$+>$+ $@<$1>$2 success, return triple
-
- # match failed, attempt to match with "general" rules (wildcards);
- # if this fails then try matching top level domain to find relay domain
- R<$+@$-> $:$>4$1 restore original address
-
- EOF
-
- cat - $$.S17 >> $outf <<'EOF'
-
- ######################################
- # Ruleset 17 -- channel matching #
- ######################################
-
- #
- # This rule takes a full domain address and trys to match it with a
- # domain given on the LHS of a rule.
- # If one matches, the "<address>host.network" triple given on the RHS
- # is returned. Else "<address>" is returned.
- #
-
- S17
- R$+@$J $@<$1@$J>error unknown local subdomain error
- EOF
-
- #
- # complete ruleset 17
- #
- cat >> $outf <<'EOF'
-
- R$+ $@<$1> no match, return "<address>"
- EOF
-
- if [ -f $$.S18 ]
- then cat - $$.S18 >> $outf <<'EOF'
-
- #############################################
- # Ruleset 18 -- newsgroup name matching #
- #############################################
-
- #
- # This rule takes a local address and trys to match it with a
- # newsgroup name given on the LHS of a rule.
- # If one matches, the "<name>news" double given on the RHS
- # is returned. If a relayed newsgroup is found, ruleset 3 is
- # re-entered with name@relay. Else "address" is returned.
- #
-
- S18
- # send non-local addresses straight back
- R$+@$+ $@$1@$2 not a local address
-
- EOF
- fi
-
- rm -f $$.*
- exit
-